package com.mygame.game_server;

import com.google.protobuf.GeneratedMessageV3;
import com.mygame.game_server.cmdHandle.CmdHandlerFactory;
import com.mygame.game_server.cmdHandle.ICmdHandler;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;


public final class MainMgsProcessor {

    private final Logger logger = LoggerFactory.getLogger(MainMgsProcessor.class);

    /**
     * 单例
     */
    static private final MainMgsProcessor _instance = new MainMgsProcessor();

    /**
     *  创建一个单线程的线程池
     */
    private  final ExecutorService _es = Executors.newSingleThreadExecutor((newRunnable) ->{
        Thread newThread = new Thread(newRunnable);
        newThread.setName("MainMsgProcessor");
        return newThread;
    });

    private MainMgsProcessor() {
    }

    static public MainMgsProcessor getInstance() {
        return _instance;
    }

    /**
     * 下发逻辑
     * @param ctx
     * @param msg
     */
    public void process(ChannelHandlerContext ctx, Object msg) {


        logger.info(
                "收到客户端消息, msgClazz = {}, msgBody = {}",
                msg.getClass().getSimpleName(),
                msg
        );
        // 保证单线程执行
        _es.submit(()->{
            try {
                //  获取命令处理器
                ICmdHandler<? extends GeneratedMessageV3> cmdHandler = CmdHandlerFactory.getInstance(msg.getClass());

                if (null != cmdHandler) {
                    cmdHandler.handle(ctx, cast(msg));
                }

            } catch (Exception ex) {
                // 记录错误日志
                logger.error(ex.getMessage(), ex);
            }
        });



    }

    /**
     * 转型
     *
     * @param msg
     * @param <T>
     * @return
     */
    private static  <T extends GeneratedMessageV3> T cast(Object msg) {
        if (null == msg) {
            return null;
        } else {
            return (T)msg;
        }
    }

    /**
     * 处理runnable是例
     * @param r
     */
    public void process(Runnable r) {
        if (null == r) {
            return;
        }

        _es.submit(r);
    }
}
